using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;

namespace Beetle;

public abstract class Package : IDisposable
{
	private Dictionary<long, ag> m_a = new Dictionary<long, ag>();

	private bool m_b = true;

	public int BufferOffset;

	public int BufferCount;

	private p c = p.f();

	public EventPacketRecievMessage ReceiveMessage;

	private PacketRecieveMessagerArgs d = new PacketRecieveMessagerArgs(null, null);

	public IChannel Channel;

	protected IDataWriter Writer;

	private IDataWriter e;

	private bool f;

	[CompilerGenerated]
	private bool g;

	[CompilerGenerated]
	private Encoding h;

	public bool ReadSinglePackage
	{
		[CompilerGenerated]
		get
		{
			return g;
		}
		[CompilerGenerated]
		set
		{
			g = value;
		}
	}

	public bool LittleEndian
	{
		get
		{
			return this.m_b;
		}
		set
		{
			this.m_b = value;
			if (Writer != null)
			{
				Writer.LittleEndian = value;
			}
			if (e != null)
			{
				e.LittleEndian = value;
			}
		}
	}

	public Encoding Coding
	{
		[CompilerGenerated]
		get
		{
			return h;
		}
		[CompilerGenerated]
		set
		{
			h = value;
		}
	}

	public Package()
	{
		Coding = Encoding.UTF8;
		ReadSinglePackage = false;
	}

	internal void a(long A_0, ag A_1)
	{
		lock (this.m_a)
		{
			this.m_a[A_0] = A_1;
		}
	}

	public Package(IChannel channel)
	{
		LittleEndian = channel.LittleEndian;
		((aq)channel).s = this;
		Channel = channel;
		Coding = channel.Coding;
		((aq)channel).t = ImportReceiveData;
		((aq)channel).u = MessageWrite;
		((aq)channel).v = MessageWrited;
		d.Channel = channel;
		CreateWriterReader();
	}

	public virtual object WriteCast(object message)
	{
		return message;
	}

	public virtual object ReadCast(object message)
	{
		return message;
	}

	public void GetPools()
	{
	}

	public abstract void MessageWrite(IMessage msg, IDataWriter writer);

	public virtual void MessageWrited(IMessage msg, IDataWriter writer)
	{
	}

	public abstract IMessage MessageRead(IDataReader reader);

	public void CreateWriterReader()
	{
		Writer = new x(TcpUtils.g);
		Writer.LittleEndian = LittleEndian;
		((x)Writer).e = Coding;
		((x)Writer).set_Channel((aq)Channel);
		e = new x(TcpUtils.g);
		((x)e).e = Coding;
		((x)e).set_Channel((aq)Channel);
		e.LittleEndian = LittleEndian;
		if (Channel != null && !c.f(((aq)Channel).f) && Channel.Server != null)
		{
			b();
		}
	}

	public void MessageToArraySegment(object msg, ByteArraySegment data)
	{
		try
		{
			MessageWrite((IMessage)WriteCast(msg), e);
			e.Position = 0L;
			data.Import((Stream)e);
		}
		finally
		{
			((x)e).Reset();
		}
	}

	internal void b()
	{
		((aq)Channel).j = "package reset!";
		Channel.Dispose();
	}

	public void ImportReceiveData(object sender, ChannelReceiveEventArgs e)
	{
		Import(e.Data.Array, 0, e.Data.Count);
	}

	public abstract void Import(byte[] data, int start, int count);

	protected virtual void OnMessageDataReader(IDataWriter writer)
	{
		Interlocked.Increment(ref TcpUtils.ReceiveMessages);
		IMessage a_ = null;
		try
		{
			writer.Position = 0L;
			a_ = MessageRead((IDataReader)writer);
		}
		catch (Exception ex)
		{
			throw ex;
		}
		finally
		{
			((x)writer).b(A_0: false);
		}
		a(a_, null);
	}

	protected virtual void OnReceiveMessage(PacketRecieveMessagerArgs e)
	{
		if (e.Message is ICallBackMessage)
		{
			ICallBackMessage callBackMessage = (ICallBackMessage)e.Message;
			ag value = null;
			if (this.m_a.TryGetValue(callBackMessage.MessageID, out value))
			{
				lock (this.m_a)
				{
					this.m_a.Remove(callBackMessage.MessageID);
				}
				value.b(Channel, callBackMessage, value.b());
			}
			else if (ReceiveMessage != null)
			{
				ReceiveMessage(e);
			}
		}
		else if (ReceiveMessage != null)
		{
			ReceiveMessage(e);
		}
	}

	internal void a(IMessage A_0, object A_1)
	{
		try
		{
			d.Message = ReadCast(A_0);
			OnReceiveMessage(d);
		}
		catch (Exception innererr)
		{
			throw new LogicException(innererr, "message handler error!");
		}
	}

	protected virtual void OnDisposed()
	{
		if (Writer != null)
		{
			((x)Writer).set_Channel(null);
			((x)Writer).b(A_0: true);
			Writer = null;
		}
		if (e != null)
		{
			((x)e).set_Channel(null);
			((x)e).b(A_0: true);
			e = null;
		}
		this.m_a.Clear();
		d.Channel = null;
		d.Message = null;
		d = null;
		ReceiveMessage = null;
		Channel = null;
	}

	public void Dispose()
	{
		lock (this)
		{
			if (!f)
			{
				f = true;
				OnDisposed();
			}
		}
	}
}
